package cn.broadsense.biz.service.impl;

import cn.broadsense.biz.bo.DataItemAuditingBo;
import cn.broadsense.biz.bo.DataItemBo;
import cn.broadsense.biz.bo.DataItemQueryBo;
import cn.broadsense.biz.convert.DataItemConvert;
import cn.broadsense.biz.domain.*;
import cn.broadsense.biz.dto.DataItemDto;
import cn.broadsense.biz.dto.ItemTagTemplateDto;
import cn.broadsense.biz.mapper.*;
import cn.broadsense.biz.service.DataItemChannelService;
import cn.broadsense.biz.service.DataItemService;
import cn.broadsense.common.exception.ServiceException;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author bs
 * @description 针对表【t_data_item(点位事项数据)】的数据库操作Service实现
 * @createDate 2024-09-06 14:37:10
 */
@RequiredArgsConstructor
@Service
public class DataItemServiceImpl extends ServiceImpl<DataItemMapper, DataItem>
        implements DataItemService {

    private final DataItemMapper dataItemMapper;

    private final DataItemConvert dataItemConvert;

    private final ItemTagTemplateMapper itemTagTemplateMapper;

    private final ChannelMapper channelMapper;


    private final ItemTagTemplateDetailsMapper itemTagTemplateDetailsMapper;

    private final ItemTagMapper itemTagMapper;

    private final DataItemChannelService dataItemChannelService;


    @Override
    public List<DataItem> findList(DataItemQueryBo queryBo) {
        return super.lambdaQuery()
                .eq(!Objects.isNull(queryBo.getCollectUserId()), DataItem::getCollectUserId, queryBo.getCollectUserId())
                .and(StringUtils.isNotBlank(queryBo.getName()), dataItemLambdaQueryWrapper -> {
                    dataItemLambdaQueryWrapper.like(StrUtil.isNotBlank(queryBo.getName()), DataItem::getItemCode, queryBo.getName()).or().like(StrUtil.isNotBlank(queryBo.getName()), DataItem::getChannelCode, queryBo.getName());
                })
                .like(StrUtil.isNotBlank(queryBo.getItemCode()), DataItem::getItemCode, queryBo.getItemCode())
                .like(StrUtil.isNotBlank(queryBo.getCollectUserName()), DataItem::getCollectUserName, queryBo.getCollectUserName())
                .like(StrUtil.isNotBlank(queryBo.getChannelName()), DataItem::getChannelName, queryBo.getChannelName())
                .in(!Objects.isNull(queryBo.getStatusList()) && !queryBo.getStatusList().isEmpty(), DataItem::getStatus, queryBo.getStatusList())
                .eq(queryBo.getStatus() != null, DataItem::getStatus, queryBo.getStatus())
                .ge(queryBo.getStartTime() != null, DataItem::getCreateTime, queryBo.getStartTime())
                .le(queryBo.getEndTime() != null, DataItem::getCreateTime, queryBo.getEndTime())
                .isNotNull(queryBo.getHoldStatus() != null && queryBo.getHoldStatus().equals(1), DataItem::getHoldCollectData)
                .orderByDesc(DataItem::getCreateTime).list();
    }

    @Override
    public void saveDataItem(DataItemBo dataItemBo) {
        ItemTagTemplate itemTagTemplate = itemTagTemplateMapper.selectById(dataItemBo.getTemplateId());
        if (itemTagTemplate == null) {
            throw new ServiceException("模板不存在");
        }
        Channel channel = channelMapper.selectById(dataItemBo.getChannelId());
        if (channel == null) {
            throw new ServiceException("点位不存在");
        }
        //查看当前点位是否有存在的事项
        DataItem dataItem2 = dataItemMapper.selectOne(Wrappers.<DataItem>lambdaQuery()
                .eq(DataItem::getChannelId, dataItemBo.getChannelId())
                .in(DataItem::getStatus, 0, 1, 2).last("limit 1"));
        if (dataItem2 != null) {
            throw new ServiceException("当前点位已存在事项未完成的事项");
        }

        DataItem dataItem = new DataItem();
        dataItem.setItemCode(dataItemBo.getItemCode());
        dataItem.setChannelId(dataItemBo.getChannelId());
        dataItem.setChannelName(channel.getChannelName());
        dataItem.setChannelCode(channel.getChannelCode());
        dataItem.setItemDesc(dataItemBo.getItemDesc());
        dataItem.setCollectUserId(dataItemBo.getCollectUserId());
        dataItem.setCollectUserName(dataItemBo.getCollectUserName());
        dataItem.setTemplateId(dataItemBo.getTemplateId());
        dataItem.setTemplateName(itemTagTemplate.getTemplateName());
        dataItem.setStatus(0);
        super.save(dataItem);

    }

    @Override
    public void auditing(DataItemAuditingBo auditingBo) {
        DataItem dataItem = super.getById(auditingBo.getId());
        if (dataItem == null) {
            throw new ServiceException("数据不存在");
        }
        if (auditingBo.getStatus() != 2 && auditingBo.getStatus() != 3) {
            throw new ServiceException("审核状态错误");
        }
        if (dataItem.getStatus() == 0) {
            throw new ServiceException("数据未采集，不能审核");
        }
        if (dataItem.getStatus() > 1) {
            throw new ServiceException("数据已审核，不能再次审核");
        }
        //审核
        super.update(Wrappers.<DataItem>lambdaUpdate().set(DataItem::getStatus, auditingBo.getStatus())
                .set(DataItem::getUpdateTime, new Date())
                 .set(StrUtil.isNotBlank(auditingBo.getReason()),DataItem::getReviewResult, auditingBo.getReason())
                .set(DataItem::getReviewTime, new Date())
                .eq(DataItem::getId, dataItem.getId()));
        //更新采集状态
        if (dataItem.getStatus() == 3) {
            dataItemChannelService.update(Wrappers.<DataItemChannel>lambdaUpdate().set(DataItemChannel::getIsCollect, 1)
                    .set(DataItemChannel::getUpdateTime, new Date())
                    .eq(DataItemChannel::getChannelId, dataItem.getChannelId()));
        }

    }

    @Override
    public DataItemDto getDtoById(Long id) {
        DataItem dataItem = super.getById(id);
        if (dataItem == null) {
            throw new ServiceException("数据不存在");
        }
        DataItemDto itemDto = dataItemConvert.toItemDto(dataItem);
        //查询模板
        ItemTagTemplate itemTagTemplate = itemTagTemplateMapper.selectById(dataItem.getTemplateId());
        if (itemTagTemplate != null) {
            ItemTagTemplateDto templateDto = new ItemTagTemplateDto();
            templateDto.setId(itemTagTemplate.getId());
            templateDto.setTemplateName(itemTagTemplate.getTemplateName());
            templateDto.setTemplateSpecification(itemTagTemplate.getTemplateSpecification());
            templateDto.setRequiredQty(itemTagTemplate.getRequiredQty());
            BigDecimal total = NumberUtil.add(itemTagTemplate.getColorTagQty(), itemTagTemplate.getImgTagQty()
                    , itemTagTemplate.getTextTagQty(), itemTagTemplate.getIconTagQty(),
                    itemTagTemplate.getOtherQty());
            templateDto.setTotalQty(total.intValue());

            //查询标签详情
            List<Object> tagIds = itemTagTemplateDetailsMapper.selectObjs(Wrappers.<ItemTagTemplateDetails>lambdaQuery()
                    .select(ItemTagTemplateDetails::getItemTagId)
                    .eq(ItemTagTemplateDetails::getItemTagTemplateId, itemTagTemplate.getId()));
            //查询标签
            if (CollUtil.isNotEmpty(tagIds)) {
                List<ItemTag> itemTags = itemTagMapper.selectBatchIds(tagIds.stream().map(e -> Long.parseLong(e.toString())).collect(Collectors.toList()));
                //填充字段值
                String collectData = dataItem.getCollectData();
                if (StrUtil.isNotBlank(collectData)) {
                    JSONObject jsonObject = JSONObject.parseObject(collectData);
                    for (ItemTag itemTag : itemTags) {
                        String tagValue = jsonObject.getString(itemTag.getFieldNameDb());
                        if (StrUtil.isNotBlank(tagValue)) {
                            itemTag.setFieldValue(tagValue);
                        }
                    }
                } else {
                    String holdCollectData = dataItem.getHoldCollectData();
                    if (StrUtil.isNotBlank(holdCollectData)) {
                        JSONObject jsonObject = JSONObject.parseObject(holdCollectData);
                        for (ItemTag itemTag : itemTags) {
                            String tagValue = jsonObject.getString(itemTag.getFieldNameDb());
                            if (StrUtil.isNotBlank(tagValue)) {
                                itemTag.setFieldValue(tagValue);
                            }
                        }
                    }
                }
                templateDto.setItemTagList(itemTags);

            }
            itemDto.setItemTagTemplate(templateDto);
        }
        return itemDto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateById(DataItemDto dto) {
        LambdaUpdateWrapper<DataItem> updateWrapper = Wrappers.lambdaUpdate(DataItem.class);
        updateWrapper.set(StringUtils.isNotBlank(dto.getCollectData()), DataItem::getCollectData, dto.getCollectData());
        updateWrapper.set(DataItem::getHoldCollectData, dto.getHoldCollectData());
        updateWrapper.set(DataItem::getHoldTime, dto.getHoldTime());
        updateWrapper.set(!Objects.isNull(dto.getStatus()), DataItem::getStatus, dto.getStatus());
        updateWrapper.set(!Objects.isNull(dto.getSubmitTime()), DataItem::getSubmitTime, dto.getSubmitTime());
        updateWrapper.eq(DataItem::getId, dto.getId());
        this.update(updateWrapper);
    }
}




